package cn.com.springsource.aspect;

import cn.com.springsource.dao.Dao;
import cn.com.springsource.dao.IndexDao;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 此类中不包含独特的事务处理的aop,事务处理aop需要在 业务代码中嵌入事务
 */
@Aspect
@Component
public class NotVeryUsefulAspect {



    /**
     * execution 与within的比较:
     * execution 的粒度更加细,可控到方法的参数类型
     * within只能控制到类
     */
    @Pointcut("execution(* cn.com.springsource.dao.*.*(..))")
    public void pointCutExecution(){}

    @Before("pointCutExecution()")
    public void beforeExecution(){
        System.out.println("aspect...execution...before");
    }

    @Pointcut("within(cn.com.springsource.dao.*)")
    public void pointCutWithin(){}

    /**
     * 使用Aop  申明父类，并将默认类的实现作为 当前类的 方法进行执行，
     * 这个功能是新版本里新增的
     */
    @DeclareParents(value="cn.com.springsource.dao.*", defaultImpl= IndexDao.class)
    public static Dao dao;  //这个要表明接口


    @Before("pointCutWithin()")
    public void beforeWithin(){
        System.out.println("aspect...within...before");
    }

    /**
     * 环绕通知，注意添加参数，当前执行的连接点ProceedingJoinPoint
     * 环绕通知是处理当前要执行的方法
     * 添加了环绕通知使 before通知失效？什么情况？
     * 该例使用环绕通知改变变量参数
     */
    @Around("pointCutWithin()")
    public void AroundWithin(ProceedingJoinPoint join){
        System.out.println("aspect...within...around");
        System.out.println("a");
        Object[] args = join.getArgs();
        for (int i = 0; i < args.length; i++) {
            args[i]+="hello";
        }
        try {
            join.proceed(args);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("b");
    }



    /**
     * 后置通知
     */
    @After("pointCutWithin()")
    public void AfterTarget(){
        System.out.println("aspect...within...after");
    }

    @Pointcut("args(java.lang.String)")
    public void pointCutArgs(){}

    @Before("pointCutArgs()")
    public void beforeArgs(){
        System.out.println("aspect...args...before");
    }

    @Pointcut("@annotation(cn.com.springsource.anno.LuBan)")
    public void pointCutAnnotation(){}

    @Before("pointCutAnnotation()")
    public void beforeAnnotation(){
        System.out.println("aspect...annotation...before");
    }

    /**
     *
     */
    @Pointcut("this(cn.com.springsource.dao.IndexDao)")
    public void pointCutThis(){}

    @Before("pointCutThis()")
    public void beforeThis(){
        System.out.println("aspect...this...before");
    }


    /**
     * this是处理 代理目标对象,target是处理原对象
     * */
    @Pointcut("target(cn.com.springsource.dao.IndexDao)")
    public void pointCutTarget(){}

    @Before("pointCutTarget()")
    public void beforeTarget(){
        System.out.println("aspect...Target...before");
    }





}
